<?php
/*******************************************************************************
 * $Date:: Jan 9, 2011 12:15:42 AM                                              $
 * $Revision:                                                                  $
 * $Author:: Tuan Duong                                                        $
 * $Comment::                                                                  $
 ******************************************************************************/ 
/**
 * Description here...
 * 
 * @package Lua
 * @subpackage Bean
 * @author Tuan Duong <bacduong[at]gmail[dot]com>
 * @version
 * @property int id 
 */

class Lua_Bean_Abstract implements ArrayAccess
{
    /**
     * Variable that holds data of this bean 
     * @var array
     */
    protected $fieldData = array();
	
    /**
     * Variable that holds key of this bean
     * @var array
     */
    protected $fields = array('id');
	
    /**
     * @var array
     */
    protected $extraData = array();

	public function __construct(array $data = array())
	{
        foreach ($data as $key => $value) {
            $this->$key = $value;
        }
	}
	
	public function __get($variableName)
	{
        // TODO: check array key?
        if (isset($this->fieldData[$variableName])) {
            return $this->fieldData[$variableName];
        } else if (isset($this->extraData[$variableName])) {
            return $this->extraData[$variableName];
        } else {
            return null;
        }
	}

    public function __set($variableName, $value)
    {
        if (in_array($variableName, $this->fields)) {
            $this->fieldData[$variableName] = $value;
        } else {
            $this->extraData[$variableName] = $value;
        }
    }

    public function __isset($variableName)
    {
        
        return in_array($variableName, $this->fields)
                || array_key_exists($variableName, $this->extraData);
    }

    public function hasField($fieldName)
    {
        return in_array($fieldName, $this->fields);
    }

    /**
	 * Whether a offset exists
	 * @param mixed $offset <p>
	 * @return boolean Returns true on success or false on failure.
	 */
	public function offsetExists($variableName)
    {
        return isset($this->$variableName);
    }

	/**
	 * Offset to retrieve
	 * @param mixed $offset <p>
	 * @return mixed Can return all value types.
	 */
	public function offsetGet($variableName)
    {
        if (isset($this->$variableName)) {
            return $this->$variableName;
        }
        return $this->fieldData[$variableName];
    }

	/**
	 * Offset to set
	 * @param mixed $offset <p>
	 * @param mixed $value <p>
	 * @return void
	 */
	public function offsetSet($variableName, $value)
    {
        if (in_array($variableName, $this->fields)) {
            $this->fieldData[$variableName] = $value;
        } else {
            $this->{$variableName} = $value;
        }
    }

	/**
	 * Offset to unset
	 * @param mixed $offset <p>
	 * The offset to unset.
	 */
	public function offsetUnset($variableName)
    {
        unset($this->fieldData[$variableName]);
    }

    /**
     * Convert this bean to array exclusive extra data 
     * @return array
     */
    public function toArray()
	{
		return $this->fieldData;
	}

    public function extractData(array $fields)
    {
        $result = array();
        foreach ($fields as $field) {
            if (isset($this->fieldData[$field])) {
                $result[$field] = $this->fieldData[$field];
            }
        }
        return $result;
    }

    /**
     * Bind data
     * @param array|Zend_Db_Table_Row_Abstract $data
     */
	public function bindData($data)
    {
        if ($data instanceof Zend_Db_Table_Row_Abstract) {
            $data = $data->toArray();
        }

        if ($data && sizeof($data)){
            foreach ($data as $field => $value) {
                if (in_array($field, $this->fields)) {
                    $this->fieldData[$field] = $value;
                } else {
                    $this->extraData[$field] = $value;
                }
            }
        }
	}

    /**
     * Convert object to JSON string.
     * This function is called automatically by Zend_Json
     * @return string
     */
    public function toJson()
    {
        return json_encode($this->toArray());
    }
    
    public function isEmpty()
    {
    	return count($this->fieldData) == 0 && count($this->extraData) == 0;
    }
    
    public function isValidFieldsData()
    {
        return count($this->fieldData) > 0;
    }
    
    public function getTableName()
    {
        $className = get_class($this);
        if (strstr($className, "Abstract")) {
            throw new Lua_Exception("Cannot get table name from bean abstract object");
        }
        $tableNameUpperCase = substr($className, strlen("Lua_Bean_"));
        return Lua_Util_Common::fromCamelCase($tableNameUpperCase);
    }
	
}